<template>
    <el-header class="header">
        <div class="toolbar">
            <div :style="{ marginRight: dynamicMarginRight }">
                <svg class="icon" width="165" height="43" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
                    <!-- 文本，使用 animate 来实现逐字描边 -->
                    <text font-style="italic" font-family="Times New Roman" font-size="35" y="82" x="20" stroke="blue"
                        stroke-width="2" fill="none">
                        <!-- 动画：对每个字母设置不同的动画 -->
                        <tspan>W
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="0s"
                                fill="freeze" />
                        </tspan>
                        <tspan>e
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="0.3s"
                                fill="freeze" />
                        </tspan>
                        <tspan>l
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="0.6s"
                                fill="freeze" />
                        </tspan>
                        <tspan>c
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="0.9s"
                                fill="freeze" />
                        </tspan>
                        <tspan>o
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="1.2s"
                                fill="freeze" />
                        </tspan>
                        <tspan>m
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="1.5s"
                                fill="freeze" />
                        </tspan>
                        <tspan>e
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="1.8s"
                                fill="freeze" />
                        </tspan>
                        <tspan>
                            &nbsp
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.1s" begin="1.9s"
                                fill="freeze" />
                        </tspan>
                        <tspan>t
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="2.2s"
                                fill="freeze" />
                        </tspan>
                        <tspan>o
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="2.5s"
                                fill="freeze" />
                        </tspan>
                        <tspan>
                            &nbsp
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.1s" begin="2.6s"
                                fill="freeze" />
                        </tspan>
                        <tspan>z
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="2.9s"
                                fill="freeze" />
                        </tspan>
                        <tspan>r
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="3.2s"
                                fill="freeze" />
                        </tspan>
                        <tspan>a
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="3.5s"
                                fill="freeze" />
                        </tspan>
                        <tspan>y
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="3.8s"
                                fill="freeze" />
                        </tspan>
                        <tspan>.
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.1s" begin="3.9s"
                                fill="freeze" />
                        </tspan>
                        <tspan>f
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="4.2s"
                                fill="freeze" />
                        </tspan>
                        <tspan>u
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="4.5s"
                                fill="freeze" />
                        </tspan>
                        <tspan>n
                            <animate attributeName="stroke-dashoffset" from="500" to="0" dur="0.3s" begin="4.8s"
                                fill="freeze" />
                        </tspan>
                    </text>
                </svg>
            </div>
            <el-dropdown style="margin-right: 20px;margin-top: 5px;" class="right-div">
                <div style="font-size: 15px; cursor: pointer" v-if="!citySetted">天气</div>
                <div style="font-size: 15px; cursor: pointer; display: flex" v-if="citySetted">
                    <div style="font-size: 15px;margin-top: 3px;">{{ city }} &nbsp</div><img style="width: 22px;height:22px;
                    background-color: grey;" :src="weatherImgSrc">
                </div>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item>
                            <div>
                                <el-button class="button" @click="handleCitySettingFunc">{{ citySetted ? "切换" : "设置"
                                    }}常驻城市</el-button>
                            </div>
                        </el-dropdown-item>
                        <el-dropdown-item>
                            <div v-if="citySetted">
                                <wheather v-if="wheatherShow" :weatherInfo="weatherInfo"></wheather>
                            </div>
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <el-dropdown style="margin-right: 20px;margin-top: 5px;">
                <el-badge :value="messageSize" :max="99" :hidden="!hasMessages" type="warning" overlap>
                    <el-icon style="font-size: 22px; cursor: pointer">
                        <Bell />
                    </el-icon>
                </el-badge>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item v-for="(message, index) in pendingTaskList" :key="index">
                            <el-button @click="handleMessageFunc(message)" class="button">{{ message.title
                                }}</el-button>
                        </el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
            <el-dropdown>
                <el-image :src=url lazy style="width:30px; height:30px" class="image">
                    <!-- 自定义加载时的显示内容 -->
                    <template #loading>
                        <div class="custom-loading">
                            <div class="spinner"></div>
                            <p>加载中...</p>
                        </div>
                    </template>
                    <!-- 自定义加载失败时的显示内容 -->
                    <template #error>
                        <div class="image-slot"><el-icon><icon-picture /></el-icon></div>
                    </template>
                    <!-- 自定义图片源为空时的显示内容 -->
                    <template #empty>
                        <div class="image-slot"><el-icon><icon-picture /></el-icon></div>
                    </template>
                </el-image>
                <template #dropdown>
                    <el-dropdown-menu style="align-items: center; ">
                        <el-dropdown-item>
                            <el-button @click="memberFunc" class="button">会员</el-button>
                        </el-dropdown-item>
                        <el-dropdown-item>
                            <el-button @click="baseInfoFunc" class="button">基础信息</el-button>
                        </el-dropdown-item>
                        <el-dropdown-item>
                            <el-button @click="changePasswordFunc" class="button">修改密码</el-button>
                        </el-dropdown-item>
                        <el-dropdown-item>
                            <el-button class="button" @click="logout">退出登录</el-button>
                        </el-dropdown-item>
                        <el-dropdown-item divided><span style="text-align: center">当前用户：{{ baseInfoFormData.name
                                }}</span></el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </div>
    </el-header>

    <!-- 会员对话框 start-->
    <el-dialog :title="memberTitle" width="500px" append-to-body draggable v-model="memberOuterVisible">
        <el-card style="max-width: 480px">
            <template #header style="background-color: mediumblue;">
                <div class="card-header">
                    <span style="font-size: 20px;">乐集网VIP会员</span>
                </div>
            </template>
            <div style="border: 1px solid burlywood;background-color:antiquewhite; 
                width: 250px;padding:5px;height: 120px; border-radius:10px">
                <div style="font-size: 20px;">年度会员</div>
                <div>
                    <span style="font-size: 30px;">￥{{ memberPrice }}/年 </span>
                    <span class="strikethrough">{{ oldMemberPrice }}</span>
                </div>
                <div>
                    <span>有效期至：</span>
                    <span style="color: green;">{{ expiryDateEnd }}</span>
                </div>
            </div>
            <div style="margin-top: 10px;">
                <div style="font-size: 18px;">专属权益</div>
                <div class="text item">1. 工具类</div>
                <div class="text item">2. 家庭相册</div>
                <div class="text item">2. 周影院</div>
            </div>
            <template #footer>
                <div style="text-align: right; padding:5px">
                    <span>实付款 </span><span style="font-size: 30px; color:orangered;font-weight: bold;">￥{{ memberPrice
                        }}</span>
                    <span class="strikethrough"> {{ oldMemberPrice }}</span>
                    <el-button type="primary" @click="payFunc" style="margin-left: 10px;"
                        :disabled="member">去支付</el-button>
                </div>
            </template>
        </el-card>
    </el-dialog>
    <!-- 会员对话框 end-->

    <!-- 支付对话框 start-->
    <el-dialog :title="payTitle" width="300px" append-to-body draggable v-model="payOuterVisible"
        @close="payDialogCloseFunc">
        <div style="text-align: center;">
            <el-image :src="imageSrc" v-if="imageSrc"></el-image>
            <div style="font-weight: bold;">支付宝扫码支付</div>
        </div>

    </el-dialog>
    <!-- 支付对话框 end-->

    <!-- 基本信息设置对话框 start-->
    <el-dialog :title="baseInfoTitle" width="500px" append-to-body draggable v-model="baseInfoOuterVisible">
        <div>
            后续可用手机号密码的方式登录！
        </div>
        <hr>
        <el-row :gutter="15" style="margin-top:8px">
            <el-form :model="baseInfoFormData" :rules="baseInfoRules" :size="formSize" label-width="150px"
                ref="baseInfoFormRef" style="max-width: 600px">
                <el-col :span="24">
                    <el-form-item label="用户名" prop="name">
                        <el-input v-model="baseInfoFormData.name" placeholder="请输入用户名" clearable
                            :style="{ width: '100%' }">
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="手机号" prop="phone">
                        <el-input v-model="baseInfoFormData.phone" placeholder="请输入手机号" clearable
                            :style="{ width: '100%' }"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24" v-if="showPassword">
                    <el-form-item label="密码" prop="password">
                        <el-input v-model="baseInfoFormData.password" placeholder="请输入密码" clearable
                            :style="{ width: '100%' }" type="password" show-password></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item size="large">
                        <el-button type="primary" @click="submitBaseInfoForm(baseInfoFormRef)">保存</el-button>
                        <el-button @click="baseInfoOuterVisible = false">取消</el-button>
                        <el-button @click="resetForm(baseInfoFormRef)">重置</el-button>
                    </el-form-item>
                </el-col>
            </el-form>
        </el-row>
    </el-dialog>
    <!-- 基本信息设置对话框 end -->

    <!-- 修改密码对话框 start-->
    <el-dialog :title="changePasswordTitle" width="500px" append-to-body draggable v-model="changePasswordOuterVisible">
        <el-row :gutter="15">
            <el-form :model="changePasswordFormData" :rules="changePasswordRules" :size="formSize" label-width="150px"
                ref="changePasswordFormRef" style="max-width: 600px">
                <el-col :span="24">
                    <el-form-item label="旧密码" prop="oldPassword">
                        <el-input v-model="changePasswordFormData.oldPassword" placeholder="请输入旧密码" type="password"
                            show-password clearable :style="{ width: '100%' }">
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="新密码" prop="newPassword">
                        <el-input v-model="changePasswordFormData.newPassword" type="password" show-password
                            placeholder="请输入新密码" clearable :style="{ width: '100%' }"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="重复新密码" prop="repeatNewPassword">
                        <el-input v-model="changePasswordFormData.repeatNewPassword" type="password" show-password
                            placeholder="请重复输入新密码" clearable :style="{ width: '100%' }"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item size="large">
                        <el-button type="primary"
                            @click="submitChangePasswordForm(changePasswordFormRef)">保存</el-button>
                        <el-button @click="changePasswordOuterVisible = false">取消</el-button>
                        <el-button @click="resetForm(changePasswordFormRef)">重置</el-button>
                    </el-form-item>
                </el-col>
            </el-form>
        </el-row>
    </el-dialog>
    <!-- 修改密码对话框 end -->

    <!-- 待办事项对话框 start -->
    <el-dialog title="待办事项" width="500px" append-to-body draggable v-model="pendingTaskOuterVisible"
        v-if="pendingTaskOuterVisible">
        <pendingTask :id="pendingTaskId" :title="pendingTaskTitle" :content="pendingTaskContent"
            :remark="pendingTaskRemark"></pendingTask>
    </el-dialog>
    <!-- 待办事项对话框 end -->

    <!-- 常驻城市设置对话框 start -->
    <el-dialog title="常驻城市设置" width="330px" append-to-body draggable v-model="citySettingOuterVisible"
        v-if="citySettingOuterVisible" @close="citySettingDialogCloseFunc">
        <cityVue></cityVue>
    </el-dialog>
    <!-- 常驻城市设置对话框 end -->
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import { showErrorMsg, showSuccessMsg, resetForm } from '@/api/common'
import type { ApiResponse } from '@/api/common'
import { Menu as IconMenu, Message, Setting, ArrowDown, Picture as IconPicture } from '@element-plus/icons-vue'
import { ElMessageBox, ElNotification } from 'element-plus'
import type { FormInstance, FormRules, ComponentSize } from 'element-plus'
import { currentUserInfo, changePassword, namePhoneSetting, currentUserMemberInfo, userLogout } from "@/api/user/user";
import type { ChangePasswordRequest, CurrentUserInfo, CurrentUserMemberInfo, MemberInfoResponse, UserBaseInfoRequest } from '@/api/user/user'
import { removeAllCache, setUserInfo, getUserInfo, getToken } from "@/utils/auth";
import { useRouter } from 'vue-router';
import { precreate, latestTradeStatusGet } from "@/api/alipay/alipay";
import { Bell } from '@element-plus/icons-vue';
import pendingTask from './pendingTask.vue'
import { intervalPendingTask } from '@/api/albumCollection/albumCollection'
import type { PendingTask, IntervalPendingTaskVo } from '@/api/albumCollection/albumCollection';
import cityVue from './city/city.vue'
import { getCitySetting, getWeatherByCity, getWeatherIcon } from '@/api/city/city'
import type { WeatherInfo, CitySettingRequest } from '@/api/city/city'
import wheather from './wheather/wheather.vue'
const citySetted = ref(false)
const city = ref('')
const weatherImgSrc = ref('')
const citySettingOuterVisible = ref(false)
const handleCitySettingFunc = () => {
    citySettingOuterVisible.value = true;
}
const wheatherShow = ref(false)
const weatherInfo = ref<WeatherInfo>({
    lastUpdate: '',
    daily: [],
})
const getCity = () => {
    getCitySetting().then((res: ApiResponse<string>) => {
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            if (res.data) {
                city.value = res.data;
                citySetted.value = true;
                const formData = reactive<CitySettingRequest>({
                    city: res.data,
                })
                getWeatherByCity(formData).then((res: ApiResponse<WeatherInfo>) => {
                    if (res.data) {
                        const dailyList = res.data.daily;
                        const today = dailyList[0];
                        weatherImgSrc.value = getWeatherIcon(today.codeDay);
                        weatherInfo.value = res.data;
                        wheatherShow.value = true
                    }
                })
            }
        }
    })
}
getCity();
const citySettingDialogCloseFunc = () => {
    getCity();
}
const imageSrc = ref<string>('');
let getPayImage = () => {
    precreate().then((res: any) => {
        const imageBytes = new Uint8Array(res.data);
        const base64Image = btoa(String.fromCharCode(...imageBytes));
        imageSrc.value = `data:image/png;base64,${base64Image}`;
    })
}
const formSize = ref<ComponentSize>('default')
const changePasswordFormRef = ref<FormInstance>()
const baseInfoFormRef = ref<FormInstance>()
let changePasswordRules = reactive<FormRules<ChangePasswordRequest>>({
    oldPassword: [{
        required: true,
        message: '请输入旧密码',
        trigger: 'change'
    }],
    newPassword: [{
        required: true,
        message: '请输入新密码',
        trigger: 'change'
    }],
    repeatNewPassword: [{
        required: true,
        message: '请重复输入新密码',
        trigger: 'blur'
    }],
})
let baseInfoRules = reactive<FormRules<UserBaseInfoRequest>>({
    name: [{
        required: true,
        message: '请输入用户名',
        trigger: 'change'
    }],
    phone: [{
        required: true,
        message: '请输入手机号',
        trigger: 'change'
    }],
    password: [{
        required: true,
        message: '请输入密码',
        trigger: 'change'
    }]
})
const changePasswordFormData = reactive<ChangePasswordRequest>({
    id: null,
    oldPassword: '',
    newPassword: '',
    repeatNewPassword: '',
})
const router = useRouter();
const url = ref<string>('')
const changePasswordOuterVisible = ref(false);
const baseInfoOuterVisible = ref(false);
const memberOuterVisible = ref(false);
const payOuterVisible = ref(false);
const changePasswordTitle = ref<string>('修改密码');
const baseInfoTitle = ref<string>('基础信息');
const memberTitle = ref<string>('成为会员');
const payTitle = ref<string>('支付宝扫码支付');
const showPassword = ref(false);
const baseInfoFormData = reactive<UserBaseInfoRequest>({
    id: null,
    name: '',
    phone: '',
    password: '',
})
const initUserInfo = () => {
    currentUserInfo().then((res: ApiResponse<CurrentUserInfo>) => {
        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            url.value = res.data.wxAvatar;
            baseInfoFormData.name = res.data.name;
            baseInfoFormData.id = res.data.id;
            baseInfoFormData.phone = res.data.phone;
            // 用户信息存本地缓存
            let jsonStr = JSON.stringify(baseInfoFormData)
            const utf8Bytes = new TextEncoder().encode(jsonStr);
            const binaryString = Array.from(utf8Bytes, byte => String.fromCharCode(byte)).join('');
            setUserInfo(btoa(binaryString));
        }
    })
}
initUserInfo();
let payStatusGetTimmer: number | null = null;
const stopPayStatusGetTimmer = () => {
    if (payStatusGetTimmer) {
        clearInterval(payStatusGetTimmer);
    }
}
const payFunc = () => {
    getPayImage();
    payOuterVisible.value = true;
    payStatusGetTimmer = setInterval(() => {
        latestTradeStatusGet().then((res: ApiResponse<boolean>) => {
            if (res.status != 200) {
                // showErrorMsg(res.msg);
            } else {
                if (res.data) {
                    showSuccessMsg("支付成功，请重新登录，获取最新的功能权限！");
                    setTimeout(() => {
                        stopPayStatusGetTimmer();
                        removeCacheAndToLogin();
                    }, 1000);
                }
            }
        })
    }, 1000); // 每秒执行一次
}
const payDialogCloseFunc = () => {
    stopPayStatusGetTimmer();
}
const memberPrice = ref<string>()
const oldMemberPrice = ref<string>('40.88')
// 是否会员
const member = ref<boolean>()
const expiryDateEnd = ref<string>()
const memberFunc = () => {
    currentUserMemberInfo().then((res: MemberInfoResponse) => {
        console.log("res:", res);

        if (res.status != 200) {
            showErrorMsg(res.msg);
        } else {
            memberPrice.value = res.data.memberPrice;
            member.value = res.data.member;
            expiryDateEnd.value = res.data.expiryDateEnd;
            if (member.value) {
                memberTitle.value = '您已经是会员';
            }
        }
    })
    memberOuterVisible.value = true
}
const baseInfoFunc = () => {
    if (baseInfoFormData.phone) {
        showPassword.value = false;
    } else {
        showPassword.value = true;
    }
    baseInfoOuterVisible.value = true
}
const changePasswordFunc = () => {
    if (!baseInfoFormData.phone) {
        showErrorMsg('请先配置基本信息');
        return;
    }
    changePasswordOuterVisible.value = true;
}
const logout = () => {
    ElMessageBox.confirm(
        '确定退出当前账号么?',
        'Warning',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        userLogout().then((res: ApiResponse<string>) => {
            if (res.status != 200) {
                showErrorMsg(res.msg);
            } else {
                removeCacheAndToLogin();
            }
        })
    })
}
const removeCacheAndToLogin = () => {
    removeAllCache();
    router.push({ name: 'Login' });
}
const submitChangePasswordForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            changePasswordFormData.id = baseInfoFormData.id;
            changePassword(changePasswordFormData).then((res: ApiResponse<string>) => {
                if (res.status != 200) {
                    showErrorMsg(res.msg);
                } else {
                    showSuccessMsg("密码修改成功，请重新登录！");
                    changePasswordOuterVisible.value = false;
                    setTimeout(() => {
                        removeCacheAndToLogin();
                    }, 1000);
                }
            })
        } else {
            console.log('error submit!', fields)
        }
    })
}
const submitBaseInfoForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate((valid, fields) => {
        if (valid) {
            baseInfoFormData.id = baseInfoFormData.id;
            namePhoneSetting(baseInfoFormData).then((res: ApiResponse<string>) => {
                if (res.status != 200) {
                    showErrorMsg(res.msg);
                } else {
                    showSuccessMsg("基础信息设置成功，请重新登录！");
                    baseInfoOuterVisible.value = false;
                    setTimeout(() => {
                        removeCacheAndToLogin();
                    }, 1000);
                }
            })
        } else {
            console.log('error submit!', fields)
        }
    })
}
const pendingTaskList = ref<PendingTask[]>([]);
const currentPendingTask = ref<PendingTask>()
const messageSize = ref(0);
const hasMessages = ref(false);
const pendingTaskOuterVisible = ref(false);
const pendingTaskId = ref<number>(-1);
const pendingTaskTitle = ref<string>('');
const pendingTaskContent = ref<string>('');
const pendingTaskRemark = ref<string>('');
const handleMessageFunc = (message: PendingTask) => {
    currentPendingTask.value = message;
    pendingTaskId.value = message.id;
    pendingTaskTitle.value = message.title;
    pendingTaskContent.value = message.content;
    pendingTaskOuterVisible.value = true;
}
onMounted(() => {
    // intervalGetPendingTask();
})
let listAllPendingTaskShowId: number | null = null;
const intervalGetPendingTask = () => {
    listAllPendingTaskShowId = setInterval(() => {
        intervalPendingTask().then((res: ApiResponse<IntervalPendingTaskVo>) => {
            if (res.status != 200) {
                showErrorMsg(res.msg)
            } else {
                if (res.data) {
                    pendingTaskList.value = res.data.pendingTaskList;
                    messageSize.value = res.data.pendingTaskList.length;
                    hasMessages.value = res.data.pendingTaskList.length > 0;
                    res.data.showList.forEach(r => {
                        ElNotification({
                            title: r.title,
                            message: r.content,
                            position: 'bottom-right',
                        })
                    })
                }
            }
        })
    }, 5000)
}
onUnmounted(() => {
    if (listAllPendingTaskShowId) {
        clearInterval(listAllPendingTaskShowId);
    }
})
// 将文字居中
// 动态计算左侧div的marginRight
const marginRightTemp = ref('20px')
const leftWidthTemp = ref('90px')
const dynamicMarginRight = computed(() => {
    return `calc((100vw - ${marginRightTemp.value}*8.5)/2- ${leftWidthTemp.value}/2)`;
});

// websocket相关 start
// WebSocket 连接状态
const isConnected = ref(false)
// 存储接收到的消息
const messages = ref<string[]>([])
// WebSocket 实例
let ws: WebSocket | null = null
// 定时器ID
let pingInterval: number | null = null
// 用于控制重连延迟
let reconnectInterval: number | null = null 
// 记录重连尝试次数
const reconnectAttempts = ref(0) 
// 最大重连尝试次数
const maxReconnectAttempts = 5 
// 重连延迟时间，单位毫秒（例如 5 秒）
const reconnectDelay = 5000 

// 连接 WebSocket
const connectWebSocket = () => {
    // 此处试了无法像/api那样被代理后改写url，所以直接写死
    const userInfo = getUserInfo();
    const userId = userInfo.id;
    const token = getToken();
    ws = new WebSocket(import.meta.env.VITE_WS_URL + '/wsConnect/' + token + '/' + userId);

    ws.onopen = () => {
        isConnected.value = true
        // 每 5 秒发送一次 ping 消息
        pingInterval = setInterval(() => {
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send('ping')
                // console.log('发送 ping 消息')
            }
        }, 5000)
    }

    ws.onmessage = (event) => {
        messages.value.push(event.data)
        // console.log('接收到消息:', event.data)
        let pendingTaskVo: IntervalPendingTaskVo = JSON.parse(event.data)
        pendingTaskList.value = pendingTaskVo.pendingTaskList;
        messageSize.value = pendingTaskVo.pendingTaskList.length;
        hasMessages.value = pendingTaskVo.pendingTaskList.length > 0;
        pendingTaskVo.showList.forEach(r => {
            ElNotification({
                title: r.title,
                message: r.content,
                position: 'bottom-right',
            })
        })
    }

    ws.onclose = () => {
        isConnected.value = false
        // console.log('WebSocket连接关闭')

        // 清除定时器
        if (pingInterval !== null) {
            clearInterval(pingInterval)
        }

        // 开始重连逻辑
        attemptReconnect(); 
    }

    ws.onerror = (error) => {
        console.error('WebSocket出错:', error)
    }
}

// 尝试重连
const attemptReconnect = () => {
    if (reconnectAttempts.value < maxReconnectAttempts) {
        reconnectAttempts.value++;
        console.log(`尝试重连第 ${reconnectAttempts.value} 次...`);

        // 每次重连间隔增加，例如每次增加2秒，避免频繁重连
        reconnectInterval = setTimeout(() => {
            connectWebSocket(); // 重新连接
        }, reconnectDelay * reconnectAttempts.value);
    } else {
        console.log('已达到最大重连次数，停止重连...');
    }
}

// 发送消息
const sendMessage = () => {
    if (ws && ws.readyState === WebSocket.OPEN) {
        // ws.send('Hello, WebSocket!')
        // console.log('发送消息: Hello, WebSocket!')
    } else {
        console.log('WebSocket未连接')
    }
}

// 在组件挂载时连接 WebSocket
onMounted(() => {
    setTimeout(() => {
        connectWebSocket();
    }, 3000);
})

// 在组件卸载时关闭 WebSocket
onUnmounted(() => {
    if (ws) {
        ws.close()
    }

    // 清除定时器
    if (pingInterval !== null) {
        clearInterval(pingInterval)
    }
    if (reconnectInterval !== null) {
        clearTimeout(reconnectInterval);
    }
})
// websocket相关 end
</script>

<style scoped>
text {
    stroke-dasharray: 500;
    /* 确保路径足够长以描边 */
    stroke-dashoffset: 500;
    /* 初始隐藏描边 */
}

.header {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    color: var(--el-text-color-primary);
    border: 1px solid #ccc;
    height: 45px;
}

.toolbar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    right: 20px;
    margin-right: 1px;
}

.image {
    cursor: pointer;
}

.button {
    border: none;
}

.image-slot {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    /* background: var(--el-fill-color-light); */
    font-size: 30px;
}

.strikethrough {
    text-decoration: line-through;
}
</style>